#ifndef _OrderBook_hpp_
#define _OrderBook_hpp_

#include <functional>
#include <list>
#include <map>
#include <set>
#include <sstream>

#include "Order.hpp"
#include "Trade.hpp"

namespace FeedHandler
{
	class OnNewTradeCallback : public std::unary_function<FeedHandler::Trade, void>
	{
	public:
		typedef std::auto_ptr<OnNewTradeCallback> Ptr;

		virtual void operator()(const FeedHandler::Trade & trade) {}
	};

	class OrderBook
	{
	public:
		explicit OrderBook(OnNewTradeCallback::Ptr & onNewTrade);

		void addOrder(const Order & order);
		void deleteOrder(const Order & order);
		void modifyOrder(const Order & order);

		void trade(const Trade & trade);

		double calculateMidQuote();

		std::string toString();

	private:
		// OrderBook map
		// maps price to orders queue
		typedef std::list<Order> OrdersQueue;
		typedef std::map<double, OrdersQueue > OrderBookMap;

		// Orders in system
		// maps order id to corresponding Order object
		typedef std::set<Order> OrdersSet;

	private:
		// helper functions
		void eraseOrderFromQueue(OrderBookMap & ob, const Order & order);
		void modifyOrderInQueue(OrderBookMap & ob, const Order & order);
		void printSideOrderBook(const OrderBookMap & ob, std::stringstream & ss);

	private:
		OrderBookMap m_sellOrderBook;
		OrderBookMap m_buyOrderBook;

		OrdersSet m_orders;

		OnNewTradeCallback::Ptr m_callback;
	};
}

#endif //_OrderBook_hpp_
